class_name GameplayStateMachine
extends GameplayState
## Gameplay Hierarchy State Machine
## Version: 0.1.0

##
var blackboard: Dictionary

##
var current_state_name: String

##
var states: Dictionary = {}


func get_current_state() -> GameplayState:
	return states[current_state_name]


func get_current_state_name() -> String:
	return name + "." + states[current_state_name].get_current_state_name()


func add_transition(from_state_name: String, new_transition: GameplayStateTransition) -> void:
	assert(states.has(from_state_name), "From state is not a child of this state machine!")
	assert(new_transition, "Transition should not be empty!")

	states[from_state_name].transitions.append(new_transition)


func on_setup() -> void:
	for child in get_children():
		var state = child as GameplayState
		assert(state, "Child is not a GameplayState!")
		
		states[child.name] = state
		state.on_setup()

	var ghost_state := GameplayState.new()
	ghost_state.name = "GhostState"
	add_child(ghost_state)
	states["GhostState"] = ghost_state

	var any_state := GameplayState.new()
	any_state.name = "AnyState"
	add_child(any_state)
	states["AnyState"] = any_state
	
	current_state_name = "GhostState"

	_on_setup()


func on_enter() -> void:
	_on_enter()

	current_state_name = "GhostState"

	assert(states.has(current_state_name), "Current state is not in the states dictionary!")
	states[current_state_name].on_enter()


func on_update(delta: float) -> void:
	if try_all_transitions():
		return

	assert(states.has(current_state_name), "Current state is not in the states dictionary!")
	states[current_state_name].on_update(delta)
	
	_on_update(delta)
	
	if states.has("AnyState"):
		states["AnyState"].on_update(delta)


func on_exit() -> void:
	assert(states.has(current_state_name), "Current state is not in the states dictionary!")
	states[current_state_name].on_exit()

	_on_exit()
